Captura (snapshot) de gráfico producido con Python. Fuente: Camilo Torres.
Siempre hay que tener la herramienta adecuada para cada problema. En el caso de la programación, hay algunos lenguajes que tienen ciertas ventajas con respecto a los demás dependiendo de lo que se quiera hacer.

Fuente: Tumblr
Necesitamos:
Además sería útil que:
No necesariamente hay una única opción...

La filosofía de Python se resume en su Zen
import this
The Zen of Python, by Tim Peters Beautiful is better than ugly. Explicit is better than implicit. Simple is better than complex. Complex is better than complicated. Flat is better than nested. Sparse is better than dense. Readability counts. Special cases aren't special enough to break the rules. Although practicality beats purity. Errors should never pass silently. Unless explicitly silenced. In the face of ambiguity, refuse the temptation to guess. There should be one-- and preferably only one --obvious way to do it. Although that way may not be obvious at first unless you're Dutch. Now is better than never. Although never is often better than *right* now. If the implementation is hard to explain, it's a bad idea. If the implementation is easy to explain, it may be a good idea. Namespaces are one honking great idea -- let's do more of those!
Grandes empresas como Facebook/Meta, Dropbox, Netflix, Google y Spotify usan Python para múltiples tareas en formas muy distintas.
Su estilo, su filosofía y su sintaxis hacen a python muy popular y fácil de aprender. Es sencillo encontrar documentación de los problemas que se presenten.
Aunque sea de propósito general, gracias a muchos paquetes, las capacidades de python pueden usarse directamente en un rango muy amplio de aplicaciones.
Python y sus paquetes son muy usados y constantemente en desarrollo por grandes equipos de trabajo colaborativo
Para usar Python, hay varias opciones que requerirán una mayor o menor atención en su instalación.
Una de las formas más rápidas de empezar a trabajar con Python, sin casi preocuparse por la instalación, podría ser mediante Google Colaboratory https://colab.research.google.com/. Sin embargo, esta opción requiere conexión constante a Internet, ya que se está trabajando sobre un servidor que nos "presta" Google.
Otra opción similar es utilizando a modo de prueba JupyterLab o Jupyter Notebook https://jupyter.org/try.
Para una instalación local, se puede optar por utilizar la distribución de Anaconda (en el siguiente video se el proceso de instalación: https://www.youtube.com/watch?v=tXekbwrgxL0) o se puede descargar Python directamente de la página oficial (https://www.python.org/), instalarlo y luego usar o instalar el IDE (Integrated Development Environment) de su preferencia.
Esta última opción es la que da un mayor control sobre la instalación de Python y los paquetes que se deseen usar (por ejemplo, se puede instalar JupyterLab o Jupyter Notebook localmente sin necesidad de instalar Anaconda), pero es la que requiere una mayor atención a la instalación.
El primer ejemplo clásico de programación es escribir el código para que el computador muestre un saludo. Para esto, se usa una función de Python llamada print.
Pero, ¿qué es una función?
En un lenguaje de programación, una función puede entenderse como una caja negra. Como el control remoto de su televisor. Los ingenieros que desarrollan el control remoto cierran el objeto una vez lo construyen y por lo general elaboran un manual con las especificaciones para construir cada control. Adicionalmente, elaboran otro manual para enseñar a los usuario a usar el objeto.
The original uploader was Theresa knott at English Wikibooks., CC BY-SA 3.0, via Wikimedia Commons
Para colocar un saludo (o un texto cualquiera), se debe colocar entre comillas dobles o sencillas dentro de la función print(). Entonces, para que el computador muestre un saludo, por ejemplo Hola Mundo!, debemos escribir en código:
print('Hola Mundo!')
Hola Mundo!
print("Hola", "Mundo!", sep=" ", end="\n")
Hola Mundo!
Una variable básica o simple sirve para guardar un valor específico, ya sea numérico, texto o de otro tipo de dato con el nombre con el que se va a denominar dicha variable.
Observemos el siguiente ejemplo.
# Asignamos 1 a la variable: x
x = 1
# Damos la instrucción de imprimir por pantalla
print("El valor de la variable x es", x)
# Asignamos "¡Vamos a programar!" a la variable: y
y = "¡Vamos a programar!"
# Damos la instrucción de imprimir por pantalla
print("\nEl valor de la variable y es", y)
El valor de la variable x es 1 El valor de la variable y es ¡Vamos a programar!
En Python no es necesario declarar una variable de antemano, como ocurre en C, C++ y otros lenguajes de programación. La asignación dinámica implica que es posible cambiar el tipo de dato de una variable con tan solo reasignarle un valor. En Python, se delega al programador la responsabilidad de cuidarse de efectos no esperados al cambiar el tipo de una variable. Veamos el siguiente ejemplo.
x = 3
print('x es un número entero (int):', x)
x = 5.6
print('x ahora es número un real (float):', x)
x = '25 de mayo'
print('En cambio ahora x es una cadena (string):', x)
x es un número entero (int): 3 x ahora es número un real (float): 5.6 En cambio ahora x es una cadena (string): 25 de mayo
Vea el siguiente ejemplo
x = 1
print(x)
print(type(x))
x = 10000000000000000000000000000000000000000000000000000000001
print(x)
print(type(x))
1 <class 'int'> 10000000000000000000000000000000000000000000000000000000001 <class 'int'>
Se observan dos cosas interesantes.
Primero, el tipo de dato es una clase 'int'. Todas las variables en Python son objetos, incluidas las variables simples. Por esta razón, para trabajar en Python con total propiedad es necesario aprender acerca de Clases y Objetos (Programación orientada a objetos)
Segundo, en Python los enteros pueden ser tan grandes como desee, a diferencia de otros lenguajes.
Lo número reales son representados usando el estándar IEEE 754 double precision.
x = 1.56
print(x)
print(type(x))
1.56 <class 'float'>
El tipo booleano se utiliza para variables que solamente pueden ser 'True' o 'False', es decir, valores booleanos o lógicos. Por ejemplo:
t = True
print(t)
print(type(t))
True <class 'bool'>
Este es un tipo especial de dato utilizado para indicar que una determinada variable no contiene ningún dato.
b = None
print(b)
print(type(b))
print(b is None)
None <class 'NoneType'> True
Una variable compuesta generalmente se utiliza para almacenar más de un valor. Algunos tipos de variables compuestas son llamados estructuras de datos o tipos de dato colección. Las variables compuestas podrían llegar a ser muy diversas, cada una de ellas teniendo sus ventajas o desventajas con respecto a las demás.
Se representan en la forma $a + bj$, en donde $a$ es la parte real y $ b$ la parte imaginaria
z = 3.4 - 4j
print(z)
print(type(z))
(3.4-4j) <class 'complex'>
Las cadenas son variables que representan una secuencia de caracteres, es decir que en ellas se puede almacenar cualquier texto. Para escribir un texto en Python usamos comillas simples: '...' o comillas dobles: "...".
Como vimos, la función print es la que nos permite imprimir estos mensajes. El texto \n indica una nueva linea en el texto:
print("Una línea\nOtra línea")
Una línea Otra línea
Podemos recorrer los caracteres de la cadena de texto de la siguiente forma:
texto="cuidado_con_el_orden"
print(texto)
cuidado_con_el_orden
Extrayendo el elemento cero del texto (primer caracter):
print(texto[0])
c
Extrayendo el elemento uno del texto (segundo caracter):
print(texto[1])
u
Extrayendo el elemento cinco hasta el elemento 9 del texto (sin incluir el 9):
print(texto[5:9])
do_c
También se pueden usar índices negativos (Exclusivo de Python):
print(texto[-1])
n
print(texto[3:-1])
dado_con_el_orde
La variable compuesta (estructura o variable colección) más flexible en el nucleo de Python. Las llamamos con [ ]. Este puede guardar esencialmente cualquier tipo de elemento.
arr = [1, 2, 3, 4]
print(arr)
[1, 2, 3, 4]
Los objetos guardados no tienen que ser del mismo tipo. De hecho, no tiene que haber objetos dentro de la lista para crearla
arr = [1, 1.0, "a", True, None]
print(arr)
arr = []
print(arr)
[1, 1.0, 'a', True, None] []
De forma similar a los Strings, podemos obtener los elementos individuales de una lista a través de sus índices.
arr = [1, 2, 3, 4]
print(arr[0])
print(arr[1:3])
print(arr[-1])
1 [2, 3] 4
Es posible hacer cambios en las listas, como agregar, sobreescribir y eliminar elementos
arr.append(7)
print(arr)
arr[2] = 3.0
print(arr)
del arr[0]
print(arr)
[1, 2, 3, 4, 7] [1, 2, 3.0, 4, 7] [2, 3.0, 4, 7]
Las listas pueden incluso tener listas dentro!
arr = [1.0, "a", True, None, [1, 2, 3]]
print(arr)
[1.0, 'a', True, None, [1, 2, 3]]
Similares a las listas, solo que no podemos aplicarles cambios. Son "inmutables". Las llamamos con ( )
t1 = ("Hola mundo", 4j-1, 3333333333333333, False)
print(t1)
('Hola mundo', (-1+4j), 3333333333333333, False)
Es posible crear una tupla a partir de una lista
lis_to_tup = tuple(arr)
print(lis_to_tup)
(1.0, 'a', True, None, [1, 2, 3])
Tanto las lista como las tuplas pueden contener elementos tan complejos como se desee.
t1 = (1, 'Camilo', 24.5)
l1 = ['Maria', 'Bonita']
l2 = [t1, l1]
t2 = (l2,'manzana')
print('t1=', t1)
print('l1=', l1)
print('l2=', l2)
print('t2=', t2)
t1= (1, 'Camilo', 24.5) l1= ['Maria', 'Bonita'] l2= [(1, 'Camilo', 24.5), ['Maria', 'Bonita']] t2= ([(1, 'Camilo', 24.5), ['Maria', 'Bonita']], 'manzana')
Estos son estructuras muy distintas a las anteriores, ya que los datos guardados son indexados junto con un elemento especial llamado "Llave". Podemos verlo como una guía telefónica o una lista de contactos: el nombre es la llave del número de teléfono
Estos se llaman usando {}
contactos ={
"Juan": 6013335555,
"Ana": 6032224466,
"David": 6012556644
}
print(contactos)
{'Juan': 6013335555, 'Ana': 6032224466, 'David': 6012556644}
Cualquier elemento puede ser llave de cualquier elemento.
dic1 = {
33: "Zapato",
True: 44.1,
"Nombre": ["David", "Lisa"],
(25.5, 33.6): (33.6, 25.5)
}
print(dic1)
{33: 'Zapato', True: 44.1, 'Nombre': ['David', 'Lisa'], (25.5, 33.6): (33.6, 25.5)}
Los diccionarios pueden modificarse de las mismas maneras que una lista
contactos["Pedro"] = 6016669999
contactos["David"] = 6015224466
del contactos["Ana"]
print(contactos)
{'Juan': 6013335555, 'David': 6015224466, 'Pedro': 6016669999}
Los diccionarios son muy poderosos ya que podemos incrementar su tamaño sin generar error:
#Generar diccionario vacío
persona = {}
print(type(persona))
# Agregar llaves y sus definiciones (items)
persona['Nombre'] = 'Gengis'
persona['Apellido'] = 'Khan'
persona['Edad'] = 23
persona['Esposa'] = ['Börte Qatun','Yesugen','Qulan Qatun','Möge Qatun','Juerbiesu','Ibaqa Beki']
persona['Hijos'] = 'En estudio'
persona['Mascotas'] = {'Perro': 'Wahadi', 'Gato': 'Gotze','Leon':'Pichirilo'}
# Resultado
print(persona)
print('Hijos de', persona['Nombre'], ':', persona['Hijos'])
<class 'dict'>
{'Nombre': 'Gengis', 'Apellido': 'Khan', 'Edad': 23, 'Esposa': ['Börte Qatun', 'Yesugen', 'Qulan Qatun', 'Möge Qatun', 'Juerbiesu', 'Ibaqa Beki'], 'Hijos': 'En estudio', 'Mascotas': {'Perro': 'Wahadi', 'Gato': 'Gotze', 'Leon': 'Pichirilo'}}
Hijos de Gengis : En estudio
Del ejemplo anterior se puede observar que los diccionarios pueden contener diccionarios en su interior:
print(persona['Mascotas'])
{'Perro': 'Wahadi', 'Gato': 'Gotze', 'Leon': 'Pichirilo'}
print(persona['Mascotas']['Perro'])
Wahadi
Es posible operar variables usando el símbolo +. Cuando las variables son numéricas, se suman matemáticamente y cuando son textos se concatenan.
# "Sumar" dos textos
x = "Python es "
y = "asombroso"
z = x + y
print(z)
# Sumar dos números
n1 = 1
n2 = 5
suma = n1 + n2
print(suma)
# Escribir texto y números
print("la suma de", n1, "y", n2, "es igual", suma)
print("la suma de " + str(n1) + " y " +
str(n2) + " es igual " + str(suma))
Python es asombroso 6 la suma de 1 y 5 es igual 6 la suma de 1 y 5 es igual 6
Podemos ejecutar operaciones muy sencillas teniendo en cuenta la siguiente tabla:
| Operador | Descripción |
|---|---|
+ |
Suma |
- |
Resta |
* |
Multiplicación |
/ |
División |
** |
Potencia |
Si queremos operar:
$$ 5\times(3-5)^2-\cfrac{6}{(9)^{1/3}}$$
tenemos que escribir:
res = (5*((3-5)**2))-(6/(9**(1/3)))
print(res)
17.115500859385183
La división es una operación particularmente especial, cuando estábamos pequeños nos enseñaron a dividir enteros dando como respuesta un entero llamado cociente y un número llamado residuo. En Python podemos calcular esos valores con \\ para el cociente y % para el residuo. Por ejemplo:
res = 20 // 3
print(res)
6
res = 20 % 3
print(res)
2
Finalmente, una función elemental y útil para el tratamiento de números decimales es round. Lo usamos para redondear los valores al número de cifras decimales que deseemos:
n1 = 47 / 3
print(n1)
15.666666666666666
n2 = round(n1)
print(n2)
16
n3 = round(n1,4)
print(n3)
15.6667
| Operador | Descripción | Ejemplo |
|---|---|---|
== |
Devuelve verdadero si son iguales | 3 == 3 |
!= |
Devuelve verdadero si no son iguales | 2 != 3 |
< |
Devuelve verdadero si el primero es menor que el segundo | 4 < 3 |
> |
Devuelve verdadero si el primero es mayor que el segundo | 4 > 3 |
<= |
Devuelve verdadero si el primero es menor o igual que el segundo | 4 <= 3 |
>= |
Devuelve verdadero si el primero es mayor o igual que el segundo | 4 >= 3 |
| Operador | Descripción | Ejemplo |
|---|---|---|
and |
Devuelve verdadero si ambas condiciones son verdaderas | (3 < 4) and (5 > 1) |
or |
Devuelve verdadero si al menos una de las condiciones es verdadera | (3 < 4) or (5 < 1) |
not |
Devuelve verdadero si la condición posterior es falsa y viceversa | not 3 > 2 |
Un módulo en Python es básicamente un archivo que contiene código Python con funciones, constantes y elementos en general que podremos utilizar luego de instalar y cargar el módulo
Verifiquemos qué paquetes están instalados están en el entorno de Python que tenemos activo en este momento
# Lista de paquetes/módulos sobre el entorno
!pip list
#!conda env list
Package Version ---------------------------- -------------- absl-py 1.4.0 aiohttp 3.8.4 aiosignal 1.3.1 ansi2html 1.8.0 anyio 3.6.1 appdirs 1.4.4 argon2-cffi 21.3.0 argon2-cffi-bindings 21.2.0 arrow 1.2.3 asttokens 2.0.5 astunparse 1.6.3 async-lru 2.0.2 async-timeout 4.0.2 attrs 22.1.0 Babel 2.10.3 backcall 0.2.0 beautifulsoup4 4.11.1 bleach 5.0.1 blinker 1.4 blis 0.7.9 Brotli 1.0.9 cachetools 5.2.0 catalogue 2.0.8 certifi 2022.6.15 cffi 1.15.1 charset-normalizer 2.1.0 click 8.0.3 cmake 3.26.3 colorama 0.4.4 command-not-found 0.3 confection 0.0.4 cryptography 3.4.8 cycler 0.11.0 cymem 2.0.7 dash 2.6.1 dash-core-components 2.0.0 dash-html-components 2.0.0 dash-table 5.0.0 datasets 2.12.0 dbus-python 1.2.18 debugpy 1.6.2 decorator 5.1.1 defusedxml 0.7.1 dill 0.3.6 distro 1.7.0 distro-info 1.1build1 docker-pycreds 0.4.0 emoji 2.5.0 en-core-web-md 3.5.0 en-core-web-sm 3.5.0 entrypoints 0.4 et-xmlfile 1.1.0 executing 0.9.1 fasteners 0.14.1 fastjsonschema 2.16.1 filelock 3.12.0 Flask 2.2.1 Flask-Compress 1.12 flatbuffers 23.3.3 fonttools 4.34.4 fqdn 1.5.1 frozenlist 1.3.3 fsspec 2023.5.0 gast 0.4.0 gdown 4.7.1 gensim 4.3.1 gitdb 4.0.10 GitPython 3.1.31 google-api-core 2.8.2 google-api-python-client 2.55.0 google-auth 2.17.3 google-auth-httplib2 0.1.0 google-auth-oauthlib 1.0.0 google-pasta 0.2.0 googleapis-common-protos 1.56.4 gpg 1.16.0-unknown greenlet 1.1.2 grpcio 1.54.0 gyp 0.1 h5py 3.8.0 httplib2 0.20.4 huggingface-hub 0.14.1 idna 3.3 imageio 2.28.0 importlib-metadata 4.6.4 inflect 6.0.4 ipykernel 6.15.1 ipympl 0.9.3 ipython 8.4.0 ipython-genutils 0.2.0 ipywidgets 8.0.6 isoduration 20.11.0 itsdangerous 2.1.2 jax 0.4.8 jedi 0.18.1 jeepney 0.7.1 Jinja2 3.1.2 jlab-enhanced-cell-toolbar 3.5.1 joblib 1.2.0 json5 0.9.9 jsonpointer 2.4 jsonschema 4.17.3 jupyter_client 8.3.0 jupyter_core 5.3.1 jupyter-dash 0.4.2 jupyter-events 0.6.3 jupyter-lsp 2.2.0 jupyter_server 2.6.0 jupyter_server_terminals 0.4.4 jupyterlab 4.0.2 jupyterlab-pygments 0.2.2 jupyterlab_server 2.23.0 jupyterlab-widgets 3.0.7 keras 2.12.0 keyring 23.5.0 kiwisolver 1.4.4 langcodes 3.3.0 language-selector 0.1 launchpadlib 1.10.16 lazr.restfulclient 0.14.4 lazr.uri 1.0.6 lazy_loader 0.2 libclang 16.0.0 lightning-utilities 0.8.0 lit 16.0.3 Markdown 3.4.3 MarkupSafe 2.1.1 matplotlib 3.5.2 matplotlib-inline 0.1.3 menulibre 2.2.2 mistune 0.8.4 ml-dtypes 0.1.0 monotonic 1.6 more-itertools 8.10.0 mpmath 1.2.1 multidict 6.0.4 multiprocess 0.70.14 murmurhash 1.0.9 nbclassic 0.4.3 nbclient 0.6.6 nbconvert 6.5.0 nbformat 5.4.0 nest-asyncio 1.5.5 netifaces 0.11.0 networkx 3.1 nltk 3.8.1 nodejs 0.1.1 notebook 6.4.12 notebook_shim 0.2.3 numpy 1.23.1 nvidia-cublas-cu11 11.10.3.66 nvidia-cublas-cu12 12.1.3.1 nvidia-cuda-cupti-cu11 11.7.101 nvidia-cuda-nvrtc-cu11 11.7.99 nvidia-cuda-runtime-cu11 11.7.99 nvidia-cuda-runtime-cu12 12.1.105 nvidia-cudnn-cu11 8.5.0.96 nvidia-cudnn-cu12 8.9.1.23 nvidia-cufft-cu11 10.9.0.58 nvidia-curand-cu11 10.2.10.91 nvidia-cusolver-cu11 11.4.0.1 nvidia-cusparse-cu11 11.7.4.91 nvidia-nccl-cu11 2.14.3 nvidia-nvtx-cu11 11.7.91 oauth2client 4.1.3 oauthlib 3.2.0 olefile 0.46 opencv-python 4.7.0.72 openpyxl 3.1.2 opt-einsum 3.3.0 optional-django 0.1.0 overrides 7.3.1 packaging 21.3 pandas 1.4.3 pandocfilters 1.5.0 parso 0.8.3 pathtools 0.1.2 pathy 0.10.1 pbr 5.8.0 pexpect 4.8.0 pickleshare 0.7.5 Pillow 9.5.0 pip 23.1.2 platformdirs 3.8.0 plotly 5.9.0 preshed 3.0.8 prometheus-client 0.14.1 prompt-toolkit 3.0.30 protobuf 4.22.3 psutil 5.9.0 ptyprocess 0.7.0 pure-eval 0.2.2 pyarrow 12.0.0 pyasn1 0.4.8 pyasn1-modules 0.2.8 pycairo 1.20.1 pycparser 2.21 pydantic 1.10.9 pydot 1.4.2 Pygments 2.11.2 PyGObject 3.42.1 pyinotify 0.9.6 PyJWT 2.3.0 pyOpenSSL 21.0.0 pyparsing 2.4.7 PyQt5 5.15.6 PyQt5-sip 12.9.1 PyQtWebEngine 5.15.5 pyrsistent 0.18.1 PySocks 1.7.1 python-apt 2.4.0+ubuntu1 python-dateutil 2.8.2 python-json-logger 2.0.7 pytorch-lightning 2.0.2 pytz 2022.1 pytz-deprecation-shim 0.1.0.post0 PyWavelets 1.4.1 PyYAML 5.4.1 pyzmq 25.1.0 regex 2023.6.3 reportlab 3.6.8 requests 2.28.1 requests-oauthlib 1.3.1 responses 0.18.0 retrying 1.3.3 rfc3339-validator 0.1.4 rfc3986-validator 0.1.1 rpy2 3.5.3 rsa 4.9 safetensors 0.3.1 scikit-image 0.20.0 scikit-learn 1.2.2 scipy 1.9.0 screen-resolution-extra 0.0.0 seaborn 0.11.2 SecretStorage 3.3.1 Send2Trash 1.8.0 sentry-sdk 1.23.1 setproctitle 1.3.2 setuptools 59.6.0 six 1.16.0 smart-open 6.3.0 smmap 5.0.0 sniffio 1.2.0 soupsieve 2.3.2.post1 spacy 3.5.3 spacy-legacy 3.0.12 spacy-loggers 1.0.4 SQLAlchemy 1.4.31 srsly 2.4.6 stack-data 0.3.0 stanza 1.5.0 sympy 1.10.1 systemd-python 234 tenacity 8.0.1 tensorboard 2.12.2 tensorboard-data-server 0.7.0 tensorboard-plugin-wit 1.8.1 tensorflow 2.12.0 tensorflow-estimator 2.12.0 tensorflow-io-gcs-filesystem 0.32.0 tensorrt 8.6.1 tensorrt-bindings 8.6.1 tensorrt-libs 8.6.1 termcolor 2.3.0 terminado 0.15.0 testresources 2.0.1 textblob 0.17.1 thinc 8.1.10 threadpoolctl 3.1.0 tifffile 2023.4.12 tinycss2 1.1.1 tokenizers 0.13.3 tomli 2.0.1 torch 2.0.1 torchaudio 2.0.2 torchmetrics 0.11.4 torchvision 0.15.2 tornado 6.2 tqdm 4.65.0 traitlets 5.9.0 transformers 4.30.1 triton 2.0.0 typer 0.7.0 typing_extensions 4.5.0 tzdata 2022.1 tzlocal 4.2 ubuntu-advantage-tools 8001 ubuntu-drivers-common 0.0.0 ufw 0.36.1 unattended-upgrades 0.1 unittest2 1.1.0 uri-template 1.3.0 uritemplate 4.1.1 urllib3 1.26.15 wadllib 1.3.6 wandb 0.15.3 wasabi 1.1.2 wcwidth 0.2.5 webcolors 1.13 webencodings 0.5.1 websocket-client 1.3.3 Werkzeug 2.2.1 wheel 0.37.1 widgetsnbextension 4.0.7 wordcloud 1.9.2 wrapt 1.14.1 xgboost 1.7.5 xkit 0.0.0 xxhash 3.2.0 yarl 1.9.2 zipp 1.0.0
Mediante el siguiente código podemos instalar paquetes que necesitemos y que no estén en nuestra lista. No olvidar cambiar <Nombre del paquete> por el nombre del paquete que deseamos instalar.
# Instalar el paquete/módulo: <Nombre del paquete>
#!pip install <Nombre del paquete>
#!conda install <Nombre del paquete>
Importemos el módulo math y veamos que elementos tiene mediante el uso de la función dir():
import math
print(dir(math))
['__doc__', '__loader__', '__name__', '__package__', '__spec__', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atan2', 'atanh', 'ceil', 'comb', 'copysign', 'cos', 'cosh', 'degrees', 'dist', 'e', 'erf', 'erfc', 'exp', 'expm1', 'fabs', 'factorial', 'floor', 'fmod', 'frexp', 'fsum', 'gamma', 'gcd', 'hypot', 'inf', 'isclose', 'isfinite', 'isinf', 'isnan', 'isqrt', 'lcm', 'ldexp', 'lgamma', 'log', 'log10', 'log1p', 'log2', 'modf', 'nan', 'nextafter', 'perm', 'pi', 'pow', 'prod', 'radians', 'remainder', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'tau', 'trunc', 'ulp']
Usemos una función de dicho módulo:
print(math.acosh(1.234))
0.6714222294813827
Hagamos un gráfico en el plano cartesiano:
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(0, 4, 100)
plt.title('Ejemplo Crecimiento')
plt.plot(x, x, label=r"lineal: $y = x$")
plt.plot(x, x*x, label=r"cuadrático: $y = x^2$")
plt.plot(x, np.exp(x)-1, label=r"exponencial: $y = \mathrm{e}^x - 1$")
plt.legend()
plt.show()
Almacenemos en una variable los datos de una tabla en un archivo .csv (valores separados por comas), que se encuentra en cierta dirección web, y hagamos un histograma de una de sus variables/columnas.
import pandas as pd
import matplotlib.pyplot as plt
# En github `AprendizajeProfundo`
# en `minicurso-ciencia-de-datos`
# en carpeta `datos` de la carpeta `reduccion%20dimensiones`
# archivo `auto_clean.csv`
datos = pd.read_csv("https://raw.githubusercontent.com/AprendizajeProfundo/minicurso-ciencia-de-datos/master/reduccion%20dimensiones/datos/auto_clean.csv")
datos.hist(column = "price")
plt.show()
Copie y ejecute las siguientes instrucciones (el siguiente código)
import numpy as np
from plotly.subplots import make_subplots
import plotly.graph_objects as go
N = 100
X = np.linspace(-3, 3, N)
Y = np.linspace(-3, 3, N)
X, Y = np.meshgrid(X, Y)
mu = np.array([1, 0])
Sigma = np.array([[ 0.7 , -0.7], [-0.7, 1.3]])
pos = np.empty(X.shape + (2,))
pos[:, :, 0] = X
pos[:, :, 1] = Y
from scipy.stats import multivariate_normal
F = multivariate_normal(mu, Sigma)
Z = F.pdf(pos)
fig = go.Figure(data=[go.Surface(x=X, y=Y, z=Z)])
fig.update_traces(contours_z=dict(show=True, start=0.02, end=0.22, size=0.02,
usecolormap=True, project_z=True,
highlightcolor="white"),
contours_y=dict(show=True, start=-3, end=3, size=0.2,
usecolormap=True, project_z=True, project_x=True,
highlightcolor="white"),
contours_x=dict(show=True, start=-3, end=3, size=0.2,
usecolormap=True, project_z=True, project_y=True,
highlightcolor="white"))
fig.update_layout(autosize=False,
width=600, height=600,
margin=dict(l=65, r=50, b=65, t=90),
scene=dict(camera=dict(eye=dict(x=0, y=0, z=-2))))
fig.show()
El flujo (orden en que se ejecutan las sentencias de un programa) es secuencial si no se especifica otra cosa. Este tipo de flujo significa que las sentencias se ejecutan en secuencia, una después de otra, en el orden en que se sitúan dentro del programa. Para cambiar esta situación se utilizan las estructuras que permiten modificar el flujo secuencial del programa. Así, las estructuras de selección se utilizan para seleccionar las sentencias que se han de ejecutar a continuación y las estructuras de repetición (repetitivas o iterativas) se utilizan para repetir un conjunto de sentencias.
En Python, bajo el paradigma de programación imperativo estructurado, el flujo es regulado por tres estructuras de control:
La forma predeterminada para Python consiste en recibir y ejecutar secuencialmente las instrucciones que se le den.
Observemos el siguiente código Python
a = 1
b = 2
print("`a` =", a," y `b` =", b)
`a` = 1 y `b` = 2
En el ejemplo hay tres sentencias. Dos sentencias de asignación de valores y una sentencia de impresión. Se ejecuta estrictamente en el orden dado; si se escribe la sentencia de impresión primero, el código completo falla.
Una estructura selectiva es aquella en que se ejecutan unas acciones u otras según se cumpla o no una determinada condición.
Cuando el resultado de evaluar la condición es verdad se ejecutará una determinada acción o grupo de acciones y si el resultado es falso se ejecutará otra acción o grupo de acciones diferentes
La estructura de selección clásica es el "if"
x = 5
y = 3
if x > y:
print("el valor de x es mayor que el valor de y")
print("antes de finalizar el if")
print("después de finalizar el if")
el valor de x es mayor que el valor de y antes de finalizar el if después de finalizar el if
La estructura empieza con la palabra clave if. Luego aparece una condición lógica que es evaluada (x > y). Si la condición es verdadera, como en este caso, se ejecutan las instrucciones escritas dentro de la estructura.
Podemos extender el uso del "if" con "else if" y "else"
x = 5
y = 6
if x > y:
print(x, " es mayor que ", y)
elif y > x:
print("{} es mayor que {}".format(y,x))
else:
print("ambos números son iguales")
6 es mayor que 5
Este tercer tipo de estructura de control se usa para los casos en los cuales es necesario ejecutar una o varias instrucciones varias veces.
Al comienzo del ciclo se evalúa una condición. Si la condición es verdadera se ejecuta de nuevo el ciclo. En otro caso, termina. Corra y analice el siguiente código
contador = 0
print('Empezamos')
while contador < 15:
# Las instrucciones a repetir
print(contador,' ', end='')
contador = contador + 1
print('\nTerminamos')
Empezamos 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 Terminamos
En este caso se usa una variable de salto que va recorriendo un conjunto de valores hasta terminar.
print('Empezamos:')
for i in range(15):
# Las instrucciones a repetir
print(i, ' ', end='')
print('\nTerminamos')
Empezamos: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 Terminamos
Se usa para terminar la ejecución de un ciclo while o for. Corra el siguiente ejemplo dando diferentes valores.
print('Empezamos:')
for i in range(100):
if i == 15:
break
print(i, ' ', end='')
print('\nTerminamos')
Empezamos: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 Terminamos
Es posible incluir (o anidar) estructuras de control dentro de otras estructuras de control.
Esto es de gran utilidad para realizar programas de mayor complejidad.
Ejemplo:
x = 3
y = 5
if x > y:
for i in range(5):
print(i, ' ', end='')
x = "\nx > y"
else:
for i in reversed(range(5)):
print(i, ' ', end='')
x = "\nx <= y"
print(x)
4 3 2 1 0 x <= y
Podemos anidar el mismo tipo de estructura sin problema
for i in range(0,11):
for j in range(i):
print('*', end='')
print('')
* ** *** **** ***** ****** ******* ******** ********* **********
Todo el código que hemos visto antes tiene un pequeño problema: Ha sido escrito completamente manual. Si queríamos aplicar procesos parecidos, hubo que copiar y pegar el mismo código y actualizarlo. Incluso si queremos volver a definir variables, tuvimos que re escribirlo completamente.
Las funciones en Python nos permiten re utilizar código de una forma sencilla y rápida. Definimos un código de manera premeditada y este únicamente corre en el momento que lo llamemos.
para definir una función justamente usamos def. Hagamos una función "Hola Mundo"
def hola_mundo(name):
print("Hola mundo, mi nombre es {}".format(name))
Como se ve, no se imprime nada todavía, tenemos que llamar la nueva función.
hola_mundo("Andrés")
Hola mundo, mi nombre es Andrés
Podemos definir cualquier tipo de código y utilizar cualquier estructura que hemos visto.
def create_contacts(name_list, phone_list):
contacts = {}
for name, number in zip(name_list, phone_list):
contacts[name] = number
print(contacts)
nombres = ["David", "Sara", "Santiago", "Diana"]
numeros = [2323, 55555, 23497234, 68420342]
create_contacts(nombres, numeros)
{'David': 2323, 'Sara': 55555, 'Santiago': 23497234, 'Diana': 68420342}
las funciones también pueden retornar variables cuando se llaman usando return
def get_evens(number_list):
even = []
for num in number_list:
if num % 2 == 0:
even.append(num)
return(even)
numbers = [12312341521, 33453125, 11, 23, 56, 12394871434, 77777776, 12314]
for i in get_evens(numbers):
print(i)
56 12394871434 77777776 12314
Un ejemplo final de lo que podemos aplicar con las funciones
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams["figure.figsize"] = [7.50, 3.50]
plt.rcParams["figure.autolayout"] = True
def plot_function(f, bounds=(-10,10), color="blue"):
x = np.linspace(bounds[0], bounds[1], 100)
plt.plot(x, f(x), color=color)
def f(x):
return np.sin(x) + x + x * np.sin(x)
plot_function(np.sin, (-5,5))
plot_function(f, color="red")
plt.show()
Compliquemos un poco la situación
¿Alguno conoce la "ecuación de Batman"?

def plot_symmetric(f, bounds=(-10,10), color="blue"):
x = np.linspace(bounds[0], bounds[1], 100)
plt.plot(x, f(x), color=color)
plt.plot(np.flip(-x), f(np.flip(-x)), color=color)
def y1(x):
return abs(x/2)- 0.09137*x**2 + np.sqrt(1-(abs(abs(x)-2)-1)**2) -3
def y2(x):
return 3*np.sqrt(-(x/7)**2+1)
def y3(x):
return -3*np.sqrt(-(x/7)**2+1)
def y4(x):
return 9-8*abs(x)
def y5(x):
return 1.5 - .5*abs(x) - 1.89736*(np.sqrt(3-x**2+2*abs(x))-2)
def y6(x):
return 3*abs(x)+.75
def y7(x):
return np.full(len(x), 2.25)
plt.rcParams["axes.facecolor"] = 'black'
plot_function(y1, (-4,4), color="yellow")
plot_function(y7, (-.5,.5), color="yellow")
plot_symmetric(y2, (3,7), color="yellow")
plot_symmetric(y3, (-7,-4), color="yellow")
plot_symmetric(y4, (-1,-.75), color="yellow")
plot_symmetric(y5, (-2.9,-1), color="yellow")
plot_symmetric(y6, (-.75,-.5), color="yellow")